<script lang="ts" setup>
import type { FileUploadItem } from './types';

import { computed } from 'vue';

import {
  CheckOne,
  CloseOne,
  Delete,
  FolderOpen,
  PauseOne,
  PlayOne,
  Refresh,
  Remind,
} from '@icon-park/vue-next';

import Button from '#/components/fluentui/Button.vue';
import ProgressBar from '#/components/fluentui/ProgressBar.vue';

import FileUploadItemComponent from './FileUploadItem.vue';

interface Props {
  items: FileUploadItem[];
  isUploading?: boolean;
  showUploadInfo?: boolean; // 是否显示上传信息面板
}

const props = withDefaults(defineProps<Props>(), {
  isUploading: false,
  showUploadInfo: false,
});

const emit = defineEmits<{
  cancelItem: [id: string];
  clearAll: [];
  pauseUpload: [];
  removeItem: [id: string];
  reselectFiles: []; // 添加重新选择文件事件
  retryItem: [id: string];
  startUpload: [];
}>();

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
};

// 格式化上传速度
const formatSpeed = (bytesPerSecond: number): string => {
  if (
    !bytesPerSecond ||
    bytesPerSecond <= 0 ||
    !Number.isFinite(bytesPerSecond)
  )
    return '0 B/s';
  const k = 1024;
  const sizes = ['B/s', 'KB/s', 'MB/s', 'GB/s'];
  const i = Math.floor(Math.log(bytesPerSecond) / Math.log(k));
  const value = bytesPerSecond / k ** i;
  return `${value.toFixed(i === 0 ? 0 : 1)} ${sizes[i]}`;
};

// 格式化剩余时间
const formatRemainingTime = (seconds: number): string => {
  if (!seconds || seconds <= 0 || !Number.isFinite(seconds)) return '--';

  if (seconds < 60) {
    return `${Math.ceil(seconds)}秒`;
  } else if (seconds < 3600) {
    const minutes = Math.ceil(seconds / 60);
    return `${minutes}分钟`;
  } else {
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.ceil((seconds % 3600) / 60);
    if (minutes === 60) {
      return `${hours + 1}小时`;
    }
    return hours > 0
      ? `${hours}小时${minutes > 0 ? `${minutes}分钟` : ''}`
      : `${minutes}分钟`;
  }
};

// 统计信息
const statistics = computed(() => {
  const total = props.items.length;
  const totalSize = props.items.reduce((sum, item) => sum + item.size, 0);

  const pending = props.items.filter(
    (item) => item.status === 'pending',
  ).length;
  const calculatingMd5 = props.items.filter(
    (item) => item.status === 'calculating-md5',
  ).length;
  const uploading = props.items.filter(
    (item) => item.status === 'uploading',
  ).length;
  const success = props.items.filter(
    (item) => item.status === 'success',
  ).length;
  const error = props.items.filter((item) => item.status === 'error').length;
  const cancelled = props.items.filter(
    (item) => item.status === 'cancelled',
  ).length;

  // 计算总上传速度（不包括MD5计算中的文件）
  const uploadingItems = props.items.filter(
    (item) => item.status === 'uploading',
  );
  let totalUploadSpeed = 0;
  uploadingItems.forEach((item) => {
    if (
      item.progress?.uploadSpeed &&
      Number.isFinite(item.progress.uploadSpeed) &&
      item.progress.uploadSpeed > 0
    ) {
      totalUploadSpeed += item.progress.uploadSpeed;
    }
  });

  // 计算正在处理的文件数量（MD5计算 + 上传中）
  const processingCount = calculatingMd5 + uploading;

  return {
    total,
    totalSize: formatFileSize(totalSize),
    pending,
    calculatingMd5,
    uploading,
    success,
    error,
    cancelled,
    totalUploadSpeed: Math.max(totalUploadSpeed, 0),
    processingCount,
  };
});

// 总体进度
const overallProgress = computed(() => {
  if (props.items.length === 0) return 0;

  let totalBytes = 0;
  let uploadedBytes = 0;

  for (const item of props.items) {
    totalBytes += item.size;

    if (item.status === 'success') {
      uploadedBytes += item.size;
    } else if (item.progress) {
      uploadedBytes += item.progress.totalBytesWritten;
    }
  }

  return totalBytes > 0 ? Math.round((uploadedBytes / totalBytes) * 100) : 0;
});

// 是否有可上传的文件
const hasUploadableFiles = computed(() => {
  return props.items.some(
    (item) => item.status === 'pending' || item.status === 'error',
  );
});

// 是否有正在上传的文件
const hasUploadingFiles = computed(() => {
  return props.items.some((item) => item.status === 'uploading');
});

// 获取进度条状态
const progressValidationState = computed(() => {
  if (statistics.value.error > 0) return 'error';
  if (
    statistics.value.success === statistics.value.total &&
    statistics.value.total > 0
  )
    return 'success';
  return undefined;
});
</script>

<template>
  <div class="border-border bg-card rounded-lg border p-6 shadow-sm">
    <div class="mb-4 flex items-center justify-between">
      <h3 class="text-lg font-semibold">上传队列</h3>

      <!-- 统计信息 -->
      <div v-if="items.length > 0" class="text-muted-foreground text-sm">
        总计 {{ statistics.total }} 个文件 ({{ statistics.totalSize }})
        <span
          v-if="statistics.success > 0"
          class="ml-2 inline-flex items-center text-green-600"
        >
          <CheckOne size="14" class="mr-1" /> {{ statistics.success }}
        </span>
        <span
          v-if="statistics.error > 0"
          class="ml-2 inline-flex items-center text-red-600"
        >
          <CloseOne size="14" class="mr-1" /> {{ statistics.error }}
        </span>
        <span
          v-if="statistics.uploading > 0"
          class="ml-2 inline-flex items-center text-blue-600"
        >
          <PlayOne size="14" class="mr-1" /> {{ statistics.uploading }}
        </span>
        <span
          v-if="statistics.calculatingMd5 > 0"
          class="ml-2 inline-flex items-center text-blue-500"
        >
          <Refresh size="14" class="mr-1" /> {{ statistics.calculatingMd5 }} MD5
        </span>
      </div>
    </div>

    <!-- 总体进度 -->
    <div
      v-if="items.length > 0 && (hasUploadingFiles || statistics.success > 0)"
      class="mb-4"
    >
      <div class="mb-1 flex justify-between text-sm">
        <span>总体进度</span>
        <span>{{ overallProgress }}%</span>
      </div>
      <ProgressBar
        :value="overallProgress"
        :max="100"
        thickness="medium"
        shape="rounded"
        :validation-state="progressValidationState"
      />
    </div>

    <!-- 上传信息显示 -->
    <div
      v-if="showUploadInfo && isUploading"
      class="bg-primary/10 border-primary/20 mb-4 rounded border p-3"
    >
      <div class="flex items-center justify-between">
        <div class="flex items-center">
          <!-- <div
            class="border-primary mr-2 h-4 w-4 animate-spin rounded-full border-2 border-t-transparent"
          ></div> -->
          <Spinner />
          <span class="text-primary text-sm">正在上传文件...</span>
        </div>
        <!-- 总上传速度 -->
        <div
          v-if="
            statistics.totalUploadSpeed > 0 &&
            Number.isFinite(statistics.totalUploadSpeed)
          "
          class="text-primary/80 text-xs"
        >
          {{ formatSpeed(statistics.totalUploadSpeed) }}
        </div>
      </div>

      <div class="mt-2 space-y-1">
        <!-- 显示MD5计算中的文件 -->
        <div
          v-for="item in items.filter((i) => i.status === 'calculating-md5')"
          :key="item.id"
          class="text-xs text-blue-600"
        >
          <div class="flex items-center justify-between">
            <span>{{ item.name }}</span>
            <div class="flex items-center space-x-2">
              <span>
                计算MD5:
                {{ Math.round(item.md5Progress?.percentage || 0) }}%
              </span>
            </div>
          </div>
        </div>

        <!-- 显示上传中的文件 -->
        <div
          v-for="item in items.filter((i) => i.status === 'uploading')"
          :key="item.id"
          class="text-primary/80 text-xs"
        >
          <div class="flex items-center justify-between">
            <span>{{ item.name }}</span>
            <div class="flex items-center space-x-2">
              <span> {{ item.progress?.progressPercentage || 0 }}% </span>
              <span
                v-if="
                  item.progress?.uploadSpeed &&
                  item.progress.uploadSpeed > 0 &&
                  Number.isFinite(item.progress.uploadSpeed)
                "
                class="text-primary/60"
              >
                {{ formatSpeed(item.progress.uploadSpeed) }}
              </span>
              <span
                v-if="
                  item.progress?.remainingTime &&
                  item.progress.remainingTime > 0 &&
                  Number.isFinite(item.progress.remainingTime)
                "
                class="text-primary/60"
              >
                剩余
                {{ formatRemainingTime(item.progress.remainingTime) }}
              </span>
            </div>
          </div>
        </div>
      </div>

      <div class="border-primary/20 mt-2 border-t pt-2">
        <div class="text-primary/70 flex items-center justify-between text-xs">
          <div class="flex items-center">
            <Remind
              theme="outline"
              size="12"
              fill="currentColor"
              class="mr-1"
            />
            <span>
              <template
                v-if="statistics.calculatingMd5 > 0 && statistics.uploading > 0"
              >
                正在计算MD5和上传文件，请勿关闭此对话框
              </template>
              <template v-else-if="statistics.calculatingMd5 > 0">
                正在计算文件MD5，请勿关闭此对话框
              </template>
              <template v-else> 文件正在上传中，请勿关闭此对话框 </template>
            </span>
          </div>
          <div class="text-primary/60">
            <span v-if="statistics.calculatingMd5 > 0" class="mr-2">
              {{ statistics.calculatingMd5 }} 个文件计算MD5
            </span>
            <span v-if="statistics.uploading > 1">
              {{ statistics.uploading }} 个文件同时上传
            </span>
          </div>
        </div>
      </div>
    </div>

    <!-- 文件列表 -->
    <div
      v-if="items.length === 0"
      class="text-muted-foreground py-8 text-center"
    >
      <div class="mb-2 flex justify-center text-4xl text-gray-400">
        <FolderOpen size="48" />
      </div>
      <p>暂无文件在队列中</p>
      <p class="mt-1 text-sm">拖拽文件到上方区域开始上传</p>
    </div>

    <div v-else class="space-y-3">
      <FileUploadItemComponent
        v-for="item in items"
        :key="item.id"
        :item="item"
        @remove="emit('removeItem', $event)"
        @retry="emit('retryItem', $event)"
        @cancel="emit('cancelItem', $event)"
      />
    </div>

    <!-- 操作按钮 -->
    <div
      v-if="items.length > 0"
      class="border-border mt-6 flex items-center justify-between border-t pt-4"
    >
      <div class="flex space-x-3">
        <!-- 开始/暂停上传 -->
        <Button
          v-if="!isUploading && hasUploadableFiles"
          appearance="primary"
          @click="emit('startUpload')"
        >
          <template #start>
            <PlayOne size="16" />
          </template>
          开始上传
        </Button>

        <Button
          v-if="isUploading"
          appearance="secondary"
          @click="emit('pauseUpload')"
        >
          <template #start>
            <PauseOne size="16" />
          </template>
          暂停上传
        </Button>

        <!-- 重试失败的文件 -->
        <Button
          v-if="statistics.error > 0"
          appearance="secondary"
          @click="emit('retryItem', 'all-failed')"
        >
          <template #start>
            <Refresh size="16" />
          </template>
          重试失败
        </Button>
      </div>

      <div class="flex space-x-3">
        <!-- 重新选择文件 -->
        <Button
          appearance="transparent"
          @click="emit('reselectFiles')"
          :disabled="isUploading"
        >
          <template #start>
            <FolderOpen size="16" />
          </template>
          重新选择
        </Button>

        <!-- 清空队列 -->
        <Button
          appearance="subtle"
          @click="emit('clearAll')"
          :disabled="isUploading"
        >
          <template #start>
            <Delete size="16" />
          </template>
          清空队列
        </Button>
      </div>
    </div>
  </div>
</template>
